package stack

import (
	"fmt"

	. "gitee.com/kingzyt/common/util"
)

type StackInt struct {
	list   []int
	topIdx int32
}

func NewStackInt(initCap int) *StackInt {
	if initCap <= 0 {
		initCap = 2
	}
	return &StackInt{list: make([]int, initCap)}
}

func (self *StackInt) Push(obj int) {
	oldLen := int32(len(self.list))
	if self.topIdx >= oldLen {
		self.topIdx = oldLen
		tempList := make([]int, oldLen*2)
		for i := int32(0); i < oldLen; i++ {
			tempList[i] = self.list[i]
			self.list[i] = 0
		}
		self.list = tempList
	}
	self.list[self.topIdx] = obj
	self.topIdx++
}

var intEmptyErr = fmt.Errorf("stack is emtpy")

func (self *StackInt) Pop() (rlt int, err error) {
	if self.topIdx <= 0 {
		self.topIdx = 0
		err = intEmptyErr
		return
	}
	if self.topIdx >= int32(len(self.list)) {
		self.topIdx = int32(len(self.list))
	}

	self.topIdx--
	return self.list[self.topIdx], nil
}

func (self *StackInt) PeekTop() (rlt int, err error) {
	if self.topIdx <= 0 {
		err = intEmptyErr
		return
	}
	if self.topIdx > int32(len(self.list)) {
		self.topIdx = int32(len(self.list))
	}
	return self.list[self.topIdx-1], nil
}

func (self *StackInt) Len() int32 {
	return self.topIdx
}

func (self *StackInt) IteratorElems(proc func(v int) bool) {
	if proc == nil {
		return
	}

	count := Int32Min(int32(len(self.list)), self.topIdx)
	for i := int32(0); i < count; i++ {
		if !proc(self.list[i]) {
			return
		}
	}
}
func (self *StackInt) IteratorRevElems(proc func(v int) bool) {
	if proc == nil {
		return
	}

	count := Int32Min(int32(len(self.list)), self.topIdx)
	for i := count - 1; i >= 0; i-- {
		if !proc(self.list[i]) {
			return
		}
	}
}
